package com.zenithmind.version.config.builder;

import com.zenithmind.version.config.properties.VersionSecurityProperties;
import lombok.RequiredArgsConstructor;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.stereotype.Component;

/**
 * 安全配置构建器 - 遵循建造者模式和单一职责原则，专门构建安全配置
 * 
 * @author ZenithMind Team
 * @since 2025-01-09
 */
@Component
@RequiredArgsConstructor
public class SecurityConfigBuilder {

    private final VersionSecurityProperties securityProperties;

    /**
     * 构建安全过滤器链
     * 
     * @param http HttpSecurity对象
     * @return 安全过滤器链
     * @throws Exception 配置异常
     */
    public SecurityFilterChain buildSecurityFilterChain(HttpSecurity http) throws Exception {
        return http
            .csrf(this::configureCsrf)
            .authorizeHttpRequests(this::configureAuthorization)
            .sessionManagement(this::configureSessionManagement)
            .oauth2ResourceServer(this::configureOAuth2ResourceServer)
            .build();
    }

    /**
     * 配置CSRF保护
     * 
     * @param csrf CSRF配置器
     */
    private void configureCsrf(org.springframework.security.config.annotation.web.configurers.CsrfConfigurer<HttpSecurity> csrf) {
        if (!securityProperties.isCsrfEnabled()) {
            csrf.disable();
        }
    }

    /**
     * 配置授权规则
     * 
     * @param authorize 授权配置器
     */
    private void configureAuthorization(org.springframework.security.config.annotation.web.configurers.AuthorizeHttpRequestsConfigurer<HttpSecurity>.AuthorizationManagerRequestMatcherRegistry authorize) {
        // 认证白名单
        authorize.requestMatchers(securityProperties.getAuthWhitelist().toArray(new String[0]))
                .permitAll();
        
        // 公开端点
        authorize.requestMatchers(securityProperties.getPublicEndpoints().toArray(new String[0]))
                .permitAll();
        
        // 开发者角色端点
        authorize.requestMatchers(securityProperties.getDeveloperEndpoints().toArray(new String[0]))
                .hasAnyRole("DEVELOPER", "ADMIN");
        
        // 用户角色端点
        authorize.requestMatchers(securityProperties.getUserEndpoints().toArray(new String[0]))
                .authenticated();
        
        // 管理员角色端点
        authorize.requestMatchers(securityProperties.getAdminEndpoints().toArray(new String[0]))
                .hasRole("ADMIN");
        
        // 其他请求需要认证
        authorize.anyRequest().authenticated();
    }

    /**
     * 配置会话管理
     * 
     * @param session 会话配置器
     */
    private void configureSessionManagement(org.springframework.security.config.annotation.web.configurers.SessionManagementConfigurer<HttpSecurity> session) {
        SessionCreationPolicy policy = convertSessionCreationPolicy(securityProperties.getSessionCreationPolicy());
        session.sessionCreationPolicy(policy);
    }

    /**
     * 配置OAuth2资源服务器
     * 
     * @param oauth2 OAuth2配置器
     */
    private void configureOAuth2ResourceServer(org.springframework.security.config.annotation.web.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurer<HttpSecurity> oauth2) {
        if (!securityProperties.isOauth2ResourceServerEnabled()) {
            oauth2.disable();
        }
    }

    /**
     * 转换会话创建策略
     * 
     * @param policy 属性中的策略
     * @return Spring Security的策略
     */
    private SessionCreationPolicy convertSessionCreationPolicy(VersionSecurityProperties.SessionCreationPolicy policy) {
        return switch (policy) {
            case ALWAYS -> SessionCreationPolicy.ALWAYS;
            case IF_REQUIRED -> SessionCreationPolicy.IF_REQUIRED;
            case NEVER -> SessionCreationPolicy.NEVER;
            case STATELESS -> SessionCreationPolicy.STATELESS;
        };
    }
}
